using CommunityToolkit.Maui.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MauiBuilder.Services;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;

namespace MauiBuilder.ViewModels
{
    /// <summary>
    /// 语音转文本页面的视图模型
    /// 管理语音识别功能，包括权限处理、语言选择和文本操作
    /// </summary>
    public partial class SpeechToTextViewModel : BaseViewModel, IAsyncDisposable
    {
        #region 私有字段

        private readonly ISpeechToText _speechToText;
        private readonly ITextToSpeech _textToSpeech;
        private readonly LogManager _logManager = LogManager.Instance;
        public SpeechToTextState? State => _speechToText.CurrentState;

        #endregion

        #region 可观察属性

        /// <summary>
        /// 识别的文本内容
        /// </summary>
        [ObservableProperty]
        private string _recognizedText = string.Empty;

        /// <summary>
        /// 是否正在监听
        /// </summary>
        [ObservableProperty]
        private bool _isListening = false;

        /// <summary>
        /// 当前状态文本
        /// </summary>
        [ObservableProperty]
        private string _statusText = "点击开始语音识别";

        /// <summary>
        /// 选择的语言
        /// </summary>
        [ObservableProperty]
        private Locale _selectedLanguage;

        /// <summary>
        /// 可用语言列表
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<Locale> _locales = new();

        /// <summary>
        /// 是否支持语音识别
        /// </summary>
        [ObservableProperty]
        private bool _isSpeechToTextSupported = true;

        /// <summary>
        /// 错误消息
        /// </summary>
        [ObservableProperty]
        private string _errorMessage = string.Empty;

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        public SpeechToTextViewModel(ISpeechToText speechToText, ITextToSpeech textToSpeech)
        {
            _speechToText = speechToText;
            _textToSpeech = textToSpeech;


            _logManager.LogInfo("SpeechToTextViewModel 初始化");


            InitializeAsync();
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 初始化
        /// </summary>
        private async void InitializeAsync()
        {
            try
            {
                _logManager.LogInfo("开始初始化语音识别功能");

                Locales.CollectionChanged += HandleLocalesCollectionChanged;
                _speechToText.StateChanged += HandleSpeechToTextStateChanged;
                _speechToText.RecognitionResultCompleted += HandleRecognitionResultCompleted;

                await SetLocalesCommand.ExecuteAsync(CancellationToken.None);

                // 检查权限状态
                var permissionStatus = await Permissions.CheckStatusAsync<Permissions.Microphone>();
                if (permissionStatus == PermissionStatus.Granted)
                {
                    IsSpeechToTextSupported = true;
                    StatusText = "准备就绪，点击开始语音识别";
                    _logManager.LogInfo("麦克风权限已授予，语音识别功能可用");
                }
                else
                {
                    IsSpeechToTextSupported = true; // 仍然支持，但需要权限
                    StatusText = "需要麦克风权限才能使用语音识别";
                    _logManager.LogWarning("麦克风权限未授予");
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = $"初始化失败: {ex.Message}";
                StatusText = "初始化失败";
                IsSpeechToTextSupported = false;
                _logManager.LogError($"语音识别初始化失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 开始监听
        /// </summary>
        private async Task StartListening()
        {
            try
            {
                _logManager.LogInfo("开始语音监听");
                ErrorMessage = string.Empty;
                IsListening = true;
                StatusText = "正在监听，请说话...";

                // 首先检查并请求权限
                var isGranted = await _speechToText.RequestPermissions(CancellationToken.None);
                if (!isGranted)
                {
                    ErrorMessage = "需要麦克风权限才能使用语音识别功能";
                    StatusText = "权限被拒绝";
                    _logManager.LogWarning("麦克风权限被拒绝");
                    return;
                }
                if (Connectivity.NetworkAccess != NetworkAccess.Internet)
                {
                    StatusText = "Internet connection is required";
                    return;
                }

                _speechToText.RecognitionResultUpdated += HandleRecognitionResultUpdated;
                await _speechToText.StartListenAsync(new SpeechToTextOptions { Culture = CultureInfo.CurrentCulture, ShouldReportPartialResults = true }, CancellationToken.None);

                //var recognitionResult = await _speechToText.ListenAsync(
                //    CultureInfo.GetCultureInfo(SelectedLanguage.Language),
                //    new Progress<string>(partialText =>
                //    {
                //        // 实时显示部分识别结果
                //        RecognizedText += partialText;
                //        StatusText = "正在识别...";
                //    }),
                //    CancellationToken.None);

                //if (recognitionResult.IsSuccessful)
                //{
                //    RecognizedText = recognitionResult.Text;
                //    StatusText = "识别完成";
                //    _logManager.LogInfo($"语音识别成功: {recognitionResult.Text}");
                //}
                //else
                //{
                //    ErrorMessage = $"识别失败: {recognitionResult.Exception?.Message ?? "未知错误"}";
                //    StatusText = "识别失败";
                //    _logManager.LogError($"语音识别失败: {recognitionResult.Exception?.Message}");
                //}
            }
            catch (PermissionException ex)
            {
                ErrorMessage = "需要麦克风权限";
                StatusText = "监听失败";
                await AppShell.DisplayAlertAsync("权限错误", ex.Message, "确定");
                ErrorMessage = $"监听失败: {ex.Message}";
            }
            catch (Exception ex)
            {
                ErrorMessage = $"监听失败: {ex.Message}";
                StatusText = "监听失败";
                _logManager.LogError($"语音监听失败: {ex.Message}");
            }
            finally
            {
                IsListening = false;
            }
        }

        /// <summary>
        /// 停止监听
        /// </summary>
        private async Task StopListening()
        {
            try
            {
                _logManager.LogInfo("停止语音监听");
                await _speechToText.StopListenAsync(CancellationToken.None);
                _speechToText.RecognitionResultUpdated -= HandleRecognitionResultUpdated;
                StatusText = "已停止监听";
            }
            catch (Exception ex)
            {
                ErrorMessage = $"停止监听失败: {ex.Message}";
                StatusText = "停止失败";
                _logManager.LogError($"停止语音监听失败: {ex.Message}");
            }
            finally
            {
                IsListening = false;
            }
        }

        #endregion

        #region 命令
        [RelayCommand]
        async Task SetLocales(CancellationToken token)
        {
            Locales.Clear();

            var locales = await _textToSpeech.GetLocalesAsync().WaitAsync(token);

            foreach (var locale in locales.OrderBy(x => x.Language).ThenBy(x => x.Name))
            {
                Locales.Add(locale);
            }

            // 设置默认语言为中文
            SelectedLanguage = Locales.FirstOrDefault(a => a.Name.Contains("简体中文"));
        }

        /// <summary>
        /// 开始/停止语音识别命令
        /// </summary>
        [RelayCommand]
        private async Task ToggleSpeechToText()
        {
            if (!IsSpeechToTextSupported)
            {
                await Shell.Current.DisplayAlert("错误", "设备不支持语音识别功能", "确定");
                return;
            }

            try
            {
                if (IsListening)
                {
                    await StopListening();
                }
                else
                {
                    await StartListening();
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = $"操作失败: {ex.Message}";
                StatusText = "操作失败";
                IsListening = false;
                _logManager.LogError($"语音识别操作失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 清空文本命令
        /// </summary>
        [RelayCommand]
        private void ClearText()
        {
            RecognizedText = string.Empty;
            ErrorMessage = string.Empty;
            StatusText = "已清空文本";
            _logManager.LogInfo("清空识别文本");
        }

        /// <summary>
        /// 复制文本命令
        /// </summary>
        [RelayCommand]
        private async Task CopyText()
        {
            if (string.IsNullOrWhiteSpace(RecognizedText))
            {
                await Shell.Current.DisplayAlert("提示", "没有可复制的文本", "确定");
                return;
            }

            try
            {
                await Clipboard.SetTextAsync(RecognizedText);
                await Shell.Current.DisplayAlert("成功", "文本已复制到剪贴板", "确定");
                _logManager.LogInfo("文本复制成功");
            }
            catch (Exception ex)
            {
                ErrorMessage = $"复制失败: {ex.Message}";
                _logManager.LogError($"文本复制失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 分享文本命令
        /// </summary>
        [RelayCommand]
        private async Task ShareText()
        {
            if (string.IsNullOrWhiteSpace(RecognizedText))
            {
                await Shell.Current.DisplayAlert("提示", "没有可分享的文本", "确定");
                return;
            }

            try
            {
                await Share.RequestAsync(new ShareTextRequest
                {
                    Text = RecognizedText,
                    Title = "分享识别的文本"
                });
                _logManager.LogInfo("文本分享成功");
            }
            catch (Exception ex)
            {
                ErrorMessage = $"分享失败: {ex.Message}";
                _logManager.LogError($"文本分享失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 请求权限命令
        /// </summary>
        [RelayCommand]
        private async Task RequestPermissions()
        {
            try
            {
                _logManager.LogInfo("请求麦克风权限");
                var status = await Permissions.RequestAsync<Permissions.Microphone>();
                
                if (status == PermissionStatus.Granted)
                {
                    StatusText = "麦克风权限已授予";
                    ErrorMessage = string.Empty;
                    _logManager.LogInfo("麦克风权限授予成功");
                    
                    // 重新初始化
                    InitializeAsync();
                }
                else
                {
                    ErrorMessage = "需要麦克风权限才能使用语音识别功能";
                    StatusText = "权限被拒绝";
                    _logManager.LogWarning("麦克风权限被拒绝");
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = $"请求权限失败: {ex.Message}";
                StatusText = "权限请求失败";
                _logManager.LogError($"请求麦克风权限失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 语言选择改变命令
        /// </summary>
        [RelayCommand]
        private void OnLanguageChanged()
        {
            if (SelectedLanguage != null)
            {
                StatusText = $"已选择语言: {SelectedLanguage.Name}";
                _logManager.LogInfo($"语言切换为: {SelectedLanguage.Name}");
            }
        }

        #endregion

        #region 扩展方法

        void HandleRecognitionResultUpdated(object? sender, SpeechToTextRecognitionResultUpdatedEventArgs e)
        {
            RecognizedText += e.RecognitionResult;
        }

        void HandleRecognitionResultCompleted(object? sender, SpeechToTextRecognitionResultCompletedEventArgs e)
        {
            //RecognizedText = e.RecognitionResult.IsSuccessful ? e.RecognitionResult.Text : e.RecognitionResult.Exception.Message;
        }

        void HandleSpeechToTextStateChanged(object? sender, SpeechToTextStateChangedEventArgs e)
        {
            OnPropertyChanged(nameof(State));
        }

        void HandleLocalesCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            OnPropertyChanged(nameof(SelectedLanguage));
        }

        public async ValueTask DisposeAsync()
        {
            await _speechToText.DisposeAsync();
            Locales.CollectionChanged -= HandleLocalesCollectionChanged;
            _speechToText.StateChanged -= HandleSpeechToTextStateChanged;
            _speechToText.RecognitionResultCompleted -= HandleRecognitionResultCompleted;
        }
        #endregion
    }
}